#ifndef FONLINE_H_
#define FONLINE_H_

#include <zlib.h>

#include "BufMngr.h"

#define WINSOCK_VER 0x0202U
#define REMOTE_ADDRESS "localhost" /* for local SDK server */
#define REMOTE_PORT 4000U /* default port for local SDK server */
#define NET_PROTOCOL_VERSION (unsigned short)0xF0EBU
#define LANGUAGE_CODE ((int)(0x6C676E65UL)) /* "engl" */
#define DEFAULT_COMBAT_MODE (char)(0)
#define LOGIN_NAME "user"
#define LOGIN_PASS "password"

// dat file hashes
#define FOMSG0_HASH 0x748681EE // "FOTEXT.MSG"
#define FOMSG1_HASH 0x3B5F7673 // "FODLG.MSG"
#define FOMSG2_HASH 0xE402088D // "FOOBJ.MSG"
#define FOMSG3_HASH 0xDAE3381D // "FOGAME.MSG"
#define FOMSG4_HASH 0xF4F50A40 // "FOGM.MSG"
#define FOMSG5_HASH 0xE61BEA94 // "FOCOMBAT.MSG"
#define FOMSG6_HASH 0xFDA5797C // "FOQUEST.MSG"
#define FOMSG7_HASH 0x5B057228 // "FOHOLO.MSG"
#define FOMSG8_HASH 0x0E0984E4 // "FOCRAFT.MSG"
#define FOMSG9_HASH 0x5D27F70C // "FOINTERNAL.MSG"

/* proto types:
 * 	1 - armor
 * 	2 - drug
 * 	3 - weapon
 * 	4 - ammo
 * 	5 - misc
 * 	6 - car
 * 	7 - key
 * 	8 - container
 * 	9 - door
 * 	10 - grid
 * 	11 - generic
 * 	12 - wall
 */

#define FOPROTO0_HASH 0xF60E4BA5
#define FOPROTO1_HASH 0xCE846E22
#define FOPROTO2_HASH 0x77BC56B4
#define FOPROTO3_HASH 0x197E2AD5
#define FOPROTO4_HASH 0xC241E7C3
#define FOPROTO5_HASH 0x045F4738
#define FOPROTO6_HASH 0x00000000
#define FOPROTO7_HASH 0x58342081
#define FOPROTO8_HASH 0x72F26000
#define FOPROTO9_HASH 0x83C8BA84
#define FOPROTO10_HASH 0x42AC7C54
#define FOPROTO11_HASH 0xFCD05455
#define FOPROTO12_HASH 0xBAE85BD3
#define FOPROTO13_HASH 0x8354947C

#define COMPRESS (true)
#define ENCRYPT (false)

// bit positions
#define ISBITSET(bit, var) (((bit) & (var)) > 0)
#define BIT0 ((uint8_t)0x01U)
#define BIT1 ((uint8_t)0x02U)
#define BIT2 ((uint8_t)0x04U)
#define BIT3 ((uint8_t)0x08U)
#define BIT4 ((uint8_t)0x10U)
#define BIT5 ((uint8_t)0x20U)
#define BIT6 ((uint8_t)0x40U)
#define BIT7 ((uint8_t)0x80U)

class FOnline {
public:
	FOnline();
	virtual ~FOnline();

	void Dump(void);
	bool MainLoop(void);

private:
	SOCKET sock;
	z_stream zstrm;
	sockaddr_in sockdata;
	DWORD winsockver;
	BufferManager* in_buff;
	BufferManager* out_buff;
	DWORD* UID0_KEY;
	DWORD* UID1_KEY;
	DWORD* UID2_KEY;
	DWORD* UID3_KEY;
	DWORD* UID4_KEY;
	CryptManager* crypto;
	DWORD UIDXOR;
	DWORD UIDOR;
	DWORD UIDCALC;
	bool NetInited;
	bool ZlibInited;
	bool DisableZlibCompression;
	WSABUF sock_buff;

	// Sys functions
	bool Init(void);
	bool InitNet(void);
	bool NetConnect(void);
	void NetDisconnect(void);
	void ParseSocket(void);
	void NetProcess(void);
	int NetInput(bool compress);
	bool NetOutput(void);
	bool FillSockAddr(const char *name, u_short hostshort);

//	bool isNetInited() const {
//		return NetInited;
//	}
//
//	void setNetInited(bool isNetInited) {
//		NetInited = isNetInited;
//	}
//
//	bool isZlibInited() const {
//		return ZlibInited;
//	}
//
//	void setZlibInited(bool isZlibInited) {
//		ZlibInited = isZlibInited;
//	}

	// NET send event functions
	void Net_SendLogIn(const char* name, const char* pass);
	void Net_SendLoadMapOk(void);
	void Net_SendGetGameInfo(void);
	void Net_SendGetScores(void);
	void Net_SendCommand(char* cmd);
	void Net_SendDir(BYTE direction);
	void Net_SendPing(BYTE unknown);
	void Net_SendGiveGlobalInfo(BYTE unknown);
	void Net_SendGiveMap(bool, WORD, DWORD, DWORD, DWORD, DWORD);
	void Net_SendKarmaVoting(DWORD critterId, bool vote);
	void Net_SendMove(WORD pos_x, WORD pos_y, bool mode);
	void Net_SendText(char* text);
	void Net_SendTalk(void);

	// NET event handler functions
	void Net_OnCritterAction(void);
	void Net_OnCheckUID2(void);
	void Net_OnContainerInfo(void);
	void Net_OnSomeItem(void);
	void Net_OnAnimateItem(void);
	void Net_OnAddItemOnMap(void);
	void Net_OnChangeItemOnMap(void);
	void Net_OnEraseItemFromMap(void);
	void Net_OnChosenEraseItem(void);
	void Net_OnCraftResult(void);
	void Net_OnChosenClearItems(void);
	void Net_OnChosenAddItem(void);
	void Net_OnCraftAsk(void);
	void Net_OnCritterParam(void);
	void Net_OnChosenParam(void);
	void Net_OnCritterXY(void);
	void Net_OnChosenParams(void);
	void Net_OnCritterMove(void);
	void Net_OnMapTextMsg(void);
	void Net_OnMapTextMsgLex(void);
	void Net_OnCritterDir(void);
	void Net_OnMapText(void);
	void Net_OnTextMsg(bool mode);
	void Net_OnCheckUID1(void);
	void Net_OnText(void);
	void Net_OnItemLexems(void);
	void Net_OnAddCritter(bool mode);
	void Net_OnRemoveCritter(void);
	void Net_OnCritterLexems(void);
	void Net_OnCheckUID0(void);
	void Net_OnPing(void);
	void Net_OnLoginSuccess(void);
	void Net_OnRegSuccess(void);
	void Net_OnShowScreen(void);
	void Net_OnGameInfo(void);
	void Net_OnLoadMap(void);
	void Net_OnMap(void);
	void Net_OnPlayersBarterSetHide(void);
	void Net_OnPlaySound(bool mode);
	void Net_OnChosenTalk(void);
	void Net_OnPlayersBarter(void);
	void Net_OnCombatResult(void);
	void Net_OnEffect(void);
	void Net_OnFlyEffect(void);
	void Net_OnCritterSetAnims(void);
	void Net_OnCritterAnimate(void);
	void Net_OnCritterItemData(void);
	void Net_OnCritterKnockout(void);
	void Net_OnCritterMoveItem(void);
	void Net_OnProtoItemData(void);
	void Net_OnGlobalEntrances(void);
	void Net_OnCheckUID3(void);
	void Net_OnMsgData(void);
	void Net_OnFollow(void);
	void Net_OnGlobalInfo(void);
	void Net_OnViewMap(void);
	void Net_OnRunClientScript(void);
	void Net_OnDropTimers(void);
	void Net_OnUserHoloStr(void);
	void Net_OnQuest(bool mode);
	void Net_OnHoloInfo(void);
	void Net_OnScores(void);
	void Net_OnAutomapsInfo(void);
	void Net_OnCheckUID4(void);
};

#endif /* FONLINE_H_ */
